﻿<Table DataSource="listOfData" TItem="ItemData" RowClassName="@(_=>"editable-row")" Bordered TableLayout="fixed">
    <ChildContent Context="data">
        <Column TData="string" Title="Name">
            @if (!editCache[data.Id].edit)
            {
                @data.Name
            }
            else
            {
                <Input @bind-Value="editCache[data.Id].data.Name" />
            }
        </Column>
        <Column TData="string" Title="Age">
            @if (!editCache[data.Id].edit)
            {
                @data.Age
            }
            else
            {
                <Input @bind-Value="editCache[data.Id].data.Age" />
            }
        </Column>
        <Column TData="string" Title="Address">
            @if (!editCache[data.Id].edit)
            {
                @data.Address
            }
            else
            {
                <Input @bind-Value="editCache[data.Id].data.Address" />
            }
        </Column>
        <ActionColumn Title="Action">
            @if (!editCache[data.Id].edit)
            {
                <a @onclick="() => startEdit(data.Id)">Edit</a>
            }
            else
            {
                <a @onclick="() => saveEdit(data.Id)" class="save">Save</a>
                <Popconfirm Title="Sure to cancel?"
                        OnConfirm="() => cancelEdit(data.Id)"
                        OkText="Yes"
                        CancelText="No">
                    <a>Cancel</a>
                </Popconfirm>
            }
        </ActionColumn>
    </ChildContent>
</Table>

<style>
    .save {
        margin-right: 8px;
    }
</style>

@code{

    record ItemData
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
        public string Address { get; set; }
    };

    IDictionary<string, (bool edit, ItemData data)> editCache = new Dictionary<string, (bool edit, ItemData data)>();
    List<ItemData> listOfData = new();

    int i = 0;
    string editId;

    void startEdit(string id)
    {
        var data = editCache[id];
        editCache[id] = (true, data.data with { }); // add a copy in cache
    }

    void cancelEdit(string id)
    {
        var data = listOfData.FirstOrDefault(item => item.Id == id);
        editCache[id] = (false, data); // recovery
    }

    void saveEdit(string id)
    {
        var index = listOfData.FindIndex(item => item.Id == id);
        listOfData[index] = editCache[id].data; // apply the copy to data source
        editCache[id] = (false, listOfData[index]); // don't affect rows in editing
    }

    protected override void OnInitialized()
    {
        listOfData = Enumerable.Range(0, 100).Select(i => new ItemData { Id = $"{i}", Name = $"Edrward {i}", Age = 32, Address = $"London Park no. {i}" }).ToList();
        listOfData.ForEach(item =>
        {
            editCache[item.Id] = (false, item);
        });
    }
}